function fn1(x) {
    console.log(1)
    return x + 1;
}
function fn2(x) {
    console.log(2)
    return x + 2;
}
function fn3(x) {
    console.log(3)
    return x + 3;
}
function fn4(x) {
    console.log(4)
    return x + 4;
}
const a = compose(fn1, fn2, fn3, fn4);
console.log(a(1)); // 1+4+3+2+1=11
// const b = compose(fn1);
// console.log(b(1))
// const c = compose();
// console.log(c(1))

function compose(...fns) {
    if (fns.length === 0) return v => v
    else if (fns.length === 1) return (...args) => fns[0](...args)
    else {
        return function (...args) {
            //? 这里存在两种不同的写法：由于reduce初始值的问题。若指定了初始值则acc(a)为初始值，若没有指定则acc(a)为第一个fn
            //? 如果想从右至左执行reduce改为reduceRight
            return fns.reduce((acc, fn) => {
                return fn(acc)
            },...args)
        }
    }
}
